const {
	Controller
} = require('uni-cloud-router');
const crypto = require('crypto');
module.exports = class PaymentController extends Controller {
	constructor(ctx) {
		super(ctx)
	}
	/**
	 * 获得支付订单信息
	 * @param {Object} data
	 * @param {Object} module
	 * @param {Object} context
	 */
	async info() {
		//再次查询支付订单金额，支付方式
		let {
			id,
			module
		} = this.ctx.data;
		let userInfo = await this.service.user.user.getCurrentUserInfo(["balance"])
		let order = await this.service.order[module].info(id);
		let payment = this.ctx.getConfigs.platformConfigs("payment");
		let paymentList = [];
		let paymentTypeColors = {
			wxpay: "#00aa00",
			alipay: "#55aaff",
			bankcard: "#aa00ff",
			balance: "#ffaa00",
			delivery: "#ff5500",
		};
		let balance = userInfo.balance ? userInfo.balance : 0;

		for (let key in payment) {
			let item = payment[key];
			let notice = "";
			let confirm = false;
			if (key == "balance") {
				confirm = true;
				//查询账户余额
				notice = `(当前余额：￥${balance/100})`;
			} else if (key == "delivery") {
				confirm = true;
			}
			paymentList.push({
				key: key,
				icon: item.icon ? item.icon : `icon_pay_${key}`,
				color: item.color ? item.color : paymentTypeColors[key],
				name: item.payName,
				confirm,
				notice
			})
		}

		return {
			order: {
				...order,
				id,
				module
			},
			balance,
			paymentList
		}
	}

	/**
	 * 支付参数，余额支付直接扣费，并回调支付完成方法
	 * @param {Object} data
	 * @param {Object} module
	 * @param {Object} context
	 */
	async pay() {
		let {
			type, //支付方式
			id, //订单id
			module //订单类型
		} = this.ctx.data;
		const {
			uid
		} = this.ctx.auth;
		console.log("开始支付")
		//获取当前用户信息
		let userInfo = await this.service.user.user.getCurrentUserInfo(["balance", "wx_openid", "ali_openid"]);
		console.log("获取当前用户信息完成")
		//获取订单信息
		let order = await this.service.order[module].info(id);
		if (!order) {
			return {
				code: -1,
				message: "订单不存在或已支付"
			};
		}
		console.log("获取订单完成")
		order.outTradeNo = [Date.now(), crypto.createHash("md5").update(uid).digest("hex").substring(0,
				17)]
			.join("");
		//生成支付单号，避免造成重复支付
		await this.service.order[module].updateOutTradeNo(order);
		console.log("更新订单支付编号完成")
		//http://www.xxx.com/http/mall/payment/notify/app-plus/wxpay/mall
		order.notifyUrl = this.ctx.getConfigs.config("domain") + this.ctx.getConfigs.config("notify-floder") +
			"/payment/notify/" + this.ctx.context.PLATFORM + "/" + type + "/" + module;
		// console.log("order", order, userInfo)
		//获取支付参数
		return await this.service.payment[type].app(order, userInfo, async (payInfo) => {
			console.log("回调处理订单状态")
			//处理各类订单支付完成之后的回调
			return await this.service.order[module].afterPayment(payInfo, order);
		});

	}
	/**
	 * 取消订单，全额退款
	 */
	async cancel() {
		let {
			type, //支付方式
			id, //订单id
			module //订单类型
		} = this.ctx.data;

		const {
			uid
		} = this.ctx.auth;
		return await this.service.order[module].cancel(id, uid, async (order) => {
			if (order && order.payInfo) {
				//已付款订单，取消订单
				await this.service.payment[order.payInfo.type].refund({
					payInfo: order.payInfo,
					platform: order.platform,
					uid: order.user_id,
					outTradeNo: order.payInfo.outTradeNo,
					outRefundNo: order._id,
					totalFee: order.total_fee, //支付总金额
					refundFee: order.total_fee, //退款金额
					refundDesc: "取消订单", //退款原因
				})
			}
		});
	}

	/**
	 *  支付回调、payment/notify
	 *  https://uniapp.dcloud.io/uniCloud/unipay?id=%e6%94%af%e4%bb%98%e7%bb%93%e6%9e%9c%e9%80%9a%e7%9f%a5%e5%a4%84%e7%90%86
	 */
	async notify() {
		let {
			subModule
		} = this.ctx.query;
		//平台app-plus
		let platform = subModule[0];
		//支付类型，wxpay，alipay
		let provider = subModule[1];
		//新增第三个参数，支付模块
		let model = subModule[2];
		let config = this.ctx.getConfigs.config(`${platform}.payment.${provider}`);
		console.log("payment config", config);
		if (!config) {
			//其他支付
			return "支付方式错误";
		}

		let {
			header,
			result
		} = await this.service.payment[provider].verify(config, this.ctx.event, async (payInfo) => {
			//处理各类订单支付完成之后的回调
			return await this.service.order[model].afterPayment(payInfo);
		})
		//返回字符串类型
		this.ctx.headers["content-type"] = header;
		// this.ctx.headers["content-type"] = "text/xml;charset=utf-8";
		return result;
	}
}
